package com.jysz.certificate.web.action.system;

import java.util.List;

import javax.annotation.Resource;

import net.sf.navigator.menu.MenuComponent;
import net.sf.navigator.menu.MenuRepository;
import net.sf.navigator.util.LoadableResourceException;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.jysz.certificate.action.AbstractBaseAction;
import com.jysz.certificate.persistence.model.system.Menu;
import com.jysz.certificate.service.system.MenuService;
import com.jysz.webcore.exceptions.WebSystemException;
import com.jysz.webcore.utils.SshBeanUtils;

/**
 * @author <a href="mailto:javaengine@outlook.com">Kaca Rich</a>
 * 
 */
@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Namespace("/system/menu")
public class MenuAction extends AbstractBaseAction {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static final Logger LOG =  LoggerFactory.getLogger(MenuAction.class);
	
	@Resource
	private MenuService menuService;
	
	private Menu search;
	
	private Long id;
	
	private Menu entity;
	private Long parentId;
	
	@Action("left")
	public String left() {
		this.getRequest().setAttribute("repository", treeMenuCreator(0));
		return "left";
	}

	@Action(INDEX)
	public String index(){
		this.setPage(menuService.findPage(search, this.getCurrentPage(), this.getPageSize()));
		
		return INDEX;
	}
	
	@Action(ADD)
	public String add(){
		entity = new Menu();
		entity.setOrder(menuService.getMaxOrder(parentId) + 1);
		entity.setCode(menuService.genCode(parentId));
		entity.setLink("#");
		return ADD;
	}
	
	@Action(CREATE)
	public String create(){
		try{
			if(this.parentId != null && this.parentId > 0){
				entity.setParent(menuService.find(parentId));
				entity.setGrade(entity.getParent().getGrade() + 1);
//				entity.setCode(entity.getParent().getCode() + "_" + entity.getOrder());
			}else{
				entity.setGrade(1);
			}
			
			menuService.save(entity);
		}catch(Exception e){
			setFailPopMessage("创建菜单异常");
			LOG.error("创建菜单异常", e);
		}
		
		
		setRedirectUrl("index.do");
		this.setSuccessPopMessage("菜单创建成功");
		return SHOW_MSG_PAGE;
	}
	
	@Action(EDIT)
	public String edit() {
		entity = menuService.find(id);
		if(search != null){
			StringBuffer sb = new StringBuffer();
			sb.append("index.do?currentPage="+getCurrentPage());
			if(StringUtils.isNotEmpty(search.getName())){
				sb.append("&search.name="+toUtf8Encode(search.getName()));
			}
			setRedirectUrl(sb.toString());
		}else{
			setRedirectUrl("index.do?currentPage=" + getCurrentPage());
		}
		if(entity == null){
			return SHOW_MSG_PAGE;
		}
		this.parentId = entity.getParent() != null ? entity.getParent().getId() : null;
		
		return EDIT;
	}
	
	@Action(UPDATE)
	public String update() {
		
		try {
				Menu menu = menuService.find(id);
				
				String[] properties = { "name", "title", "link", "target",  "order", "code" };
				SshBeanUtils.copyProperties(entity, menu, properties);
				
				if(parentId != null && parentId != 0){
					
					menu.setParent(menuService.find(parentId));
				}else{
					//这是根菜单，序号改变，会变更code，需要改变所有子菜单code
					menuService.saveUpdateChildCode(menu);
				}
				
				menuService.save(menu);
				setSuccessPopMessage("更新数据成功");
			// 记录日志
		} catch (Exception e) {
			setFailPopMessage("更新数据异常");
			LOG.error("更新数据异常", e);
		}
		return SHOW_MSG_PAGE;
	}
	
	@Action(DESTORY)
	public String destory(){
		menuService.destory(id);
		setSuccessPopMessage("删除数据成功");
		if(search != null){
			StringBuffer sb = new StringBuffer();
			sb.append("index.do?currentPage="+getCurrentPage());
			if(StringUtils.isNotEmpty(search.getName())){
				sb.append("&search.name="+toUtf8Encode(search.getName()));
			}
			setRedirectUrl(sb.toString());
		}else{
			setRedirectUrl("index.do?currentPage="+getCurrentPage());
		}
		return SHOW_MSG_PAGE;
	}
	
	private Object treeMenuCreator(int moduleId){
	        MenuRepository repository = new MenuRepository();
	         repository.setLoadParam("/WEB-INF/menu-config.xml");
	         repository.setServletContext(this.getServletContext());
	         try {
	             repository.load();
	             this.getServletContext().setAttribute(MenuRepository.MENU_REPOSITORY_KEY, repository);

	             if (LOG.isDebugEnabled()) {
	            	 LOG.debug("struts-menu initialization successful");
	             }
	         } catch (LoadableResourceException lre) {
	             throw new WebSystemException("Failure initializing struts-menu: " +
	                     lre.getMessage());
	         }
	        repository.setDisplayers(repository.getDisplayers());

	        //	        返回某菜单栏目的顶层菜单,顶层菜单就是parentId is null
	        List<Menu> topMenus =menuService.findTopMenusByPermission(getUser()) ;
	        
	        //	        遍历菜单
	        if(topMenus != null){
	        	  for (Menu o : topMenus) {
	  	            buildTreeMenu(repository, o, null);
	  	        }
	        }
	        
	        return repository;
	    }
	
	

    /**
     * 	 递归构造菜单
     *	菜单属性有: id,序号seq,名称title,提示tip,连接url,目标窗口target,父菜单parentMenu,子菜单集合childMenus
     * @param repository
     * @param menu
     * @param menuIds
     * @param parentMenu
     */
    private void buildTreeMenu(MenuRepository repository, Menu menu,  MenuComponent parentMenu) {

            MenuComponent mc = new MenuComponent();
            mc.setName(menu.getCode());//改为CODE
            
            //FIXME:暂时用空格替代 。
            StringBuilder spaces = new StringBuilder();
            for (int i = 0; i < 12 - menu.getTitle().length(); i++) {
            	spaces.append("&nbsp;");
			}
            mc.setTitle(menu.getTitle() + spaces);
            mc.setParent(parentMenu);
            List<Menu> menus =menuService.findChildMenusByPermission(getUser(),menu); 
            		//menu.getChildMenu();
            if(menus != null && menus.size() > 0){
                for (Menu o : menus) {
                    buildTreeMenu(repository, o,  mc);
                }
            }else{
                mc.setPage(menu.getLink());
                mc.setTarget(menu.getTarget());
            }
            repository.addMenu(mc);
    }
	
	public Menu getSearch() {
		return search;
	}

	public void setSearch(Menu search) {
		this.search = search;
	}
	
	public Menu getEntity() {
		return entity;
	}

	public void setEntity(Menu entity) {
		this.entity = entity;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getParentId() {
		return parentId;
	}

	public void setParentId(Long parentId) {
		this.parentId = parentId;
	}
	
	
	public boolean isAbsUrl(String link){
		return link.toLowerCase().startsWith("http://");
	}
	
	public String convertLink(String link){
		if(isAbsUrl(link)){
			return link;
		}
		
		return isAbsUrl(link) ? link : this.getContextPath() + "/" + link;
	}
}
